package com.wiley.listener;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;

public class TestReport extends TestListenerAdapter{

	private String reportPath;

	@Override
	public void onStart(ITestContext context) {
		File htmlReportDir = new File("test-output/customizeHtml-report");  
        if (!htmlReportDir.exists()) {  
        	htmlReportDir.mkdirs();  
        }  
        String reportName = formateDate()+".html";  
        reportPath = htmlReportDir+"/"+reportName;  
        File report = new File(htmlReportDir,reportName);  
        if(report.exists()){  
            try {  
                report.createNewFile();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
        StringBuilder sb = new StringBuilder("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"
				+ "<title >UI自动化测试报告</title></head><body style=\"background-color:#99FFCC;\">"
				+ "<div id=\"top\" align=\"center\"><p style=\"font-weight:bold;\">测试用例运行结果列表</p>"
						+ "<table width=\"90%\" height=\"80\" border=\"1\" align=\"center\" cellspacing=\"0\" rules=\"all\" style=\"table-layout:fixed;\">"
								+ "<thead>"
								+ "<tr>"
								+ "<th>用例总数</th>"
								+ "<th>通过数(Passed)</th>"
								+ "<th>跳过数(Skipped)</th>"
								+ "<th>失败数(Failed)</th>"
								+ "<th>通过率(%)</th>"
								+ "<th>总耗时(ms)</th>"								
								+ "</tr>"
								+ "</thead>"
								+ "<tbody style=\"word-wrap:break-word;font-weight:bold;\" align=\"center\">"); 
        sb.append("<tr><td>");
        //用例总数
        sb.append("<input id=\"totalNum\" type=\"button\" value=\"\" disabled=\"true\" style=\"background:#99FFCC;color:blue;font-size:15px;border:0;\"/>");
        sb.append("</td><td>");
        //通过数
        sb.append("<input id=\"passNum\" type=\"button\" value=\"\" disabled=\"true\" style=\"background:#99FFCC;color:green;font-size:15px;border:0;\"/>");
        sb.append("</td><td>");
        //跳过数
        sb.append("<input id=\"skipNum\" type=\"button\" value=\"\" style=\"background:#99FFCC;color:yellow;font-size:15px;border:0;\" disabled=\"true\"/>");
        sb.append("</td><td>");
        //失败数
        sb.append("<input id=\"failNum\" type=\"button\" value=\"\" style=\"background:#99FFCC;color:red;font-size:15px;border:0;\" disabled=\"true\"/>");
        sb.append("</td><td>");
        //通过率=通过数/用例总数
        sb.append("<input id=\"percentage\" type=\"button\" value=\"\" style=\"background:#99FFCC;color:purple;font-size:15px;border:0;\" disabled=\"true\"/>");
        sb.append("</td><td>");
        //耗时=成功耗时+跳过耗时+失败耗时
        sb.append("<input id=\"totaltime\" type=\"button\" value=\"\" style=\"background:#99FFCC;color:black;font-size:15px;border:0;\" disabled=\"true\"/>");
        sb.append("</td>");
        sb.append("</tr></tbody></table>");
        sb.append("<p style=\"font-weight:bold;\"><font color=\"blue\">详情列表</font></p>"
        		+ "<table width=\"90%\" height=\"80\" border=\"1\" align=\"center\" cellspacing=\"0\" rules=\"all\" style=\"table-layout:relative;\">"
        		+ "<thead>"
        		+ "<tr>"
        		+ "<th>测试用例名</th>"
        		+ "<th>测试用例结果</th>"
        		+ "<th>耗时(ms)</th>"
        		+ "</tr>"
        		+ "</thead>"
        		+ "<tbody id=\"detail\" style=\"word-wrap:break-word;font-weight:bold;\" align=\"center\">");
        String res = sb.toString();
        try {  
            Files.write((Paths.get(reportPath)),res.getBytes("utf-8"));  
        } catch (IOException e) {  
            e.printStackTrace();  
        } 
	}
	
	@Override
	public void onTestSuccess(ITestResult result) {
		long startTime = result.getStartMillis();
		long endTime = result.getEndMillis();
		long passedTime = endTime-startTime;
		StringBuilder sb = new StringBuilder("<tr class=\"passed\"><td>");
		sb.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName());
		sb.append("</td><td><font color=\"green\">Passed</font></td>");
		//passed时间
		sb.append("<td class=\"passed_time\">"+passedTime+"</td></tr>");
		String res = sb.toString();
		try {
			Files.write((Paths.get(reportPath)),res.getBytes("utf-8"),StandardOpenOption.APPEND);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onTestSkipped(ITestResult result) {
		long startTime = result.getStartMillis();
		long endTime = result.getEndMillis();
		long skippedTime = endTime-startTime;
		StringBuilder sb = new StringBuilder("<tr class=\"skipped\"><td>");
		sb.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName());
		sb.append("</td><td><font color=\"yellow\">Skipped</font>");
		sb.append("<p align=\"left\">测试用例<font color=\"red\">跳过</font>，原因：<br>");
		sb.append("<br><a style=\"background-color:#CCCCCC;\">");
		Throwable throwable = result.getThrowable(); 
        sb.append(throwable.getMessage()); 
        sb.append("</a></p></td>");
        //skipped时间
        sb.append("<td class=\"skipped_time\">"+skippedTime+"</td></tr>");
		String res = sb.toString();
		try {
			Files.write((Paths.get(reportPath)),res.getBytes("utf-8"),StandardOpenOption.APPEND);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void onTestFailure(ITestResult result) {
		long startTime = result.getStartMillis();
		long endTime = result.getEndMillis();
		long failedTime = endTime-startTime;
		StringBuilder sb = new StringBuilder("<tr class=\"failed\"><td>");  
        sb.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName());  
        sb.append("</td><td>");  
        sb.append("<font color=\"red\">Failed</font><br>");
        sb.append("<p align=\"left\">测试用例执行<font color=\"red\">失败</font>，原因：<br>");
        sb.append("<br><a style=\"background-color:#CCCCCC;\">");
        Throwable throwable = result.getThrowable();  
        sb.append(throwable.getMessage());
        sb.append("</a></p></td>");
        //failed时间
        sb.append("<td class=\"failed_time\">"+failedTime+"</td></tr>");
        String res = sb.toString();  
        try {  
            Files.write((Paths.get(reportPath)),res.getBytes("utf-8"),StandardOpenOption.APPEND);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
	}

	@Override
	public void onFinish(ITestContext testContext) {	
		StringBuilder sb = new StringBuilder("</tbody></table><a href=\"#top\">返回顶部</a></div></body>");
		sb.append("<script type=\"text/javascript\">")
		.append("window.onload = function(){"
						+ "document.getElementById(\"totalNum\").value=document.getElementById(\"detail\").getElementsByTagName(\"tr\").length;"
						+ "document.getElementById(\"passNum\").value=document.getElementsByClassName(\"passed\").length;"
						+ "document.getElementById(\"skipNum\").value=document.getElementsByClassName(\"skipped\").length;"
						+ "document.getElementById(\"failNum\").value=document.getElementsByClassName(\"failed\").length;"
						+ "var percentage = (document.getElementsByClassName(\"passed\").length/document.getElementById(\"detail\").getElementsByTagName(\"tr\").length)*100;"
						+ "document.getElementById(\"percentage\").value = percentage.toFixed(1);"
						+ "document.getElementById(\"totaltime\").value = totaltime();"
						
		+"function totaltime(){"
						+ "return passedtime()+skippedtime()+failedtime();"
						+ "}"
		
		+"function passedtime(){"
						+ "var pass = document.getElementsByClassName(\"passed_time\");"
						+ "var sum = 0;"
						+ "for(var i=0; i<pass.length; i++){"
						+ "sum = sum+parseFloat(pass[i].innerText);"
						+ "}"
						+ "return sum;"
						+ "}"
		
		+"function failedtime(){"
				+ "var fail = document.getElementsByClassName(\"failed_time\");"
						+ "var sum = 0;"
						+ "for(var i=0; i<fail.length; i++){"
						+ "sum = sum+parseFloat(fail[i].innerText);"
						+ "}"
						+ "return sum;"
						+ "}"
		
		+"function skippedtime(){"
						+ "var skip = document.getElementsByClassName(\"skipped_time\");"
						+ "var sum = 0;"
						+ "for(var i=0; i<skip.length; i++){"
						+ "sum = sum+parseFloat(skip[i].innerText);"
						+ "}"
						+ "return sum;"
						+ "}"
		+ "}")	
		.append("</script>");
		sb.append("</html>");
		String msg = sb.toString();
		try {
			Files.write((Paths.get(reportPath)),msg.getBytes("utf-8"),StandardOpenOption.APPEND);
		} catch (IOException e) {
			e.printStackTrace();
		}
	
	}

	public static String formateDate(){
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
		Calendar cal = Calendar.getInstance();
		Date date = cal.getTime();
		return sf.format(date);
	}
}
